//
//  UITabBarControllerTestAnimatedTransitioning.m
//  MKUITestApp
//
//  Created by 苏尚进 on 2023/8/3.
//  Copyright © 2023 moon. All rights reserved.
//

#import "UITabBarControllerTestAnimatedTransitioning.h"
#import <MKUI/MKUI.h>

@interface UITabBarControllerTestAnimatedTransitioning()
@property(nonatomic,strong) UIScreenEdgePanGestureRecognizer *panGesture;
@property(nonatomic,strong) id <UIViewControllerContextTransitioning> interactiveTransitionContext;
@end
@implementation UITabBarControllerTestAnimatedTransitioning
#pragma mark - delegate:UIViewControllerAnimatedTransitioning
// synchronize with the main animation.
- (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext{
    return 0.25;
}
// This method can only be a no-op if the transition is interactive and not a percentDriven interactive transition.
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext{
    UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
    UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];
    
    [transitionContext.containerView addSubview:toView];
    [transitionContext.containerView sendSubviewToBack:toView];
    
    CGRect bounds = transitionContext.containerView.bounds;
    toView.frame = bounds;
    
    CGAffineTransform m1 = CGAffineTransformIdentity;
    m1 = CGAffineTransformConcat(m1, CGAffineTransformMakeScale(0.1, 0.1));
    
    CGAffineTransform m2 = CGAffineTransformIdentity;
    m2 = CGAffineTransformConcat(m2, CGAffineTransformMakeScale(0.1, 0.1));
    toView.transform = m2;
    toView.alpha = 0;
    [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
        fromView.transform = m1;
        fromView.alpha = 0;
        toView.transform = CGAffineTransformIdentity;
        toView.alpha = 1;
    } completion:^(BOOL finished) {
      
      //移除视图
      BOOL cancle = [transitionContext transitionWasCancelled];
      if (!cancle) {
          [fromView removeFromSuperview];
      }
        fromView.transform = CGAffineTransformIdentity;
        fromView.alpha = 1;
      //动画完成后,视图上的事件才能处理
      [transitionContext completeTransition:!cancle];
    }];
}
#pragma mark - delegate:UIViewControllerInteractiveTransitioning
- (void)startInteractiveTransition:(id <UIViewControllerContextTransitioning>)transitionContext{
    [self animateTransition:transitionContext];
    
    if(!self.panGesture){
        self.panGesture = [[UIScreenEdgePanGestureRecognizer alloc] init];
        @MK_WEAKIFY(self);
        self.panGesture.mk_moveAction.whenAction = ^(MKUIGestureRecognizerMoveAction * _Nonnull action) {
            @MK_NORMALIZE(self);
            [self _onPanGesture:action];
        };
    }
    self.interactiveTransitionContext = transitionContext;
    [transitionContext.containerView addGestureRecognizer:self.panGesture];
    
    UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    UITabBarController *tabBarController = fromViewController.tabBarController;
    NSInteger fromIndex = [tabBarController.viewControllers indexOfObject:fromViewController];
    NSInteger toIndex = [tabBarController.viewControllers indexOfObject:toViewController];
    if(fromIndex<toIndex){
        self.panGesture.edges = UIRectEdgeLeft;
    }else{
        self.panGesture.edges = UIRectEdgeRight;
    }
}
- (void)_onPanGesture:(MKUIGestureRecognizerMoveAction *)action{
    id <UIViewControllerContextTransitioning> transitionContext = self.interactiveTransitionContext;
    CGRect bounds = transitionContext.containerView.bounds;
    UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
    UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];
    UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    if(fromView.superview==nil){
        [transitionContext.containerView addSubview:fromView];
        [transitionContext.containerView bringSubviewToFront:fromView];
    }
    CGVector dis = action.moveDistance;
    CGVector v = action.moveVector;
    CGFloat progress =  ABS(dis.dx)/bounds.size.width;
    
    switch (action.gestureRecognizer.state) {
        case UIGestureRecognizerStateBegan:
        case UIGestureRecognizerStateChanged:{
            toView.alpha = MKCGFloatInterpolate(1, 0, progress);
            fromView.alpha = MKCGFloatInterpolate(0, 1, progress);
            toView.transform = MKCGAffineTransformInterpolate(CGAffineTransformIdentity, CGAffineTransformMakeScale(0.1, 0.1), progress);
            fromView.transform = MKCGAffineTransformInterpolate(CGAffineTransformMakeScale(0.1, 0.1), CGAffineTransformIdentity, progress);
            [transitionContext updateInteractiveTransition:progress];
        }
            break;
        case UIGestureRecognizerStateCancelled:
        case UIGestureRecognizerStateEnded:{
            BOOL cancel = (self.panGesture.edges==UIRectEdgeLeft && v.dx<0)||(self.panGesture.edges==UIRectEdgeRight && v.dx>0);
            [UIView animateWithDuration:0.25 animations:^{
                if(cancel){
                    toView.alpha = 1;
                    fromView.alpha = 0;
                    toView.transform = CGAffineTransformIdentity;
                    fromView.transform = CGAffineTransformMakeScale(0.1, 0.1);
                }else{
                    toView.alpha = 0;
                    fromView.alpha = 1;
                    toView.transform = CGAffineTransformMakeScale(0.1, 0.1);
                    fromView.transform = CGAffineTransformIdentity;
                }
            } completion:^(BOOL finished) {
                toView.transform = CGAffineTransformIdentity;
                toView.alpha = 1;
                fromView.alpha = 1;
                
                fromView.transform = CGAffineTransformIdentity;
                if(cancel){
                    [fromView removeFromSuperview];
                    [transitionContext cancelInteractiveTransition];
//                    [transitionContext completeTransition:cancel];
                }else{
                    [toView removeFromSuperview];
                    [transitionContext.containerView removeGestureRecognizer:self.panGesture];
                    [transitionContext finishInteractiveTransition];
//                    [transitionContext completeTransition:cancel];
                    if(self.whenChange){
                        self.whenChange(fromViewController);
                    }
                }
            }];
        }
            break;
        default:
            break;
    }
}
//@optional
//@property(nonatomic, readonly) CGFloat completionSpeed;
//@property(nonatomic, readonly) UIViewAnimationCurve completionCurve;
//
///// In 10.0, if an object conforming to UIViewControllerAnimatedTransitioning is
///// known to be interruptible, it is possible to start it as if it was not
///// interactive and then interrupt the transition and interact with it. In this
///// case, implement this method and return NO. If an interactor does not
///// implement this method, YES is assumed.
//@property (nonatomic, readonly) BOOL wantsInteractiveStart API_AVAILABLE(ios(10.0));
@end
